<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<style type="text/css"></style>
</head>
<body>


<script src="/lib/threejs/three.js-master/build/three.js"></script>
<script src="/lib/threejs/three.js-master_test/examples/js/controls/OrbitControls.js"></script>

<script type="text/javascript">
	var vs={};
	vs.radian_to_degree=function(radian){
		var degree=radian*180/Math.PI;
		return degree;
	}
	vs.degree_to_radian=function(degree){
		var radian=Math.PI*degree/180;
		return radian;
	}
	vs.get_distance=function(a,b){
		b=b||{x:0,y:0};
		return Math.sqrt(
				Math.pow((a.x-b.x),2)
				+Math.pow((a.y-b.y),2)
			)
	}
	vs.sin=function(radian){
		var r=Math.sin(radian);
		return r;
	}
	vs.cos=function(radian){
		var r=Math.cos(radian);
		return r;
	}
	vs.tan=function(radian){
		var r=Math.tan(radian);
		return r;
	}
	vs.point_in_polygon=function(point, vs) {
	    // ray-casting algorithm based on
	    // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
	    
	    var x = point[0], y = point[1];
	    
	    var inside = false;
	    for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
	        var xi = vs[i][0], yi = vs[i][1];
	        var xj = vs[j][0], yj = vs[j][1];
	        
	        var intersect = ((yi > y) != (yj > y))
	            && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
	        if (intersect) inside = !inside;
	    }
	    
	    return inside;
	}
	vs.dataURItoBlob=function(dataURI) {
	  // convert base64/URLEncoded data component to raw binary data held in a string
	  var byteString;
	  if (dataURI.split(',')[0].indexOf('base64') >= 0)
	  	byteString = atob(dataURI.split(',')[1]);
	  else
	  	byteString = unescape(dataURI.split(',')[1]);

	  // separate out the mime component
	  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

	  // write the bytes of the string to a typed array
	  var ia = new Uint8Array(byteString.length);
	  for (var i = 0; i < byteString.length; i++) {
	  	ia[i] = byteString.charCodeAt(i);
	  }

	  return new Blob([ia], {type:mimeString});
	}
	vs.getQueryStringByName=function(name) {
	    var result = location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i"));
	    if (result == null || result.length < 1) {
	        return "";
	    }
	    return result[1];
	}
</script>


<script type="text/javascript">

	var Vector = (function () {
		function Vector(x, y, z) {
			this.x = x;
			this.y = y;
			this.z = z;
		}
		Vector.times = function (k, v) {
			return new Vector(k * v.x, k * v.y, k * v.z);
		};
		Vector.minus = function (v1, v2) {
			return new Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
		};
		Vector.plus = function (v1, v2) {
			return new Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
		};
		Vector.dot = function (v1, v2) {
			return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
		};
		Vector.mag = function (v) {
			return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
		};
		Vector.norm = function (v) {
			var mag = Vector.mag(v);
			var div = (mag === 0) ? Infinity : 1.0 / mag;
			return Vector.times(div, v);
		};
		Vector.cross = function (v1, v2) {
			return new Vector(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x);
		};
		return Vector;
	}());
			
	const EPSILON=0.000001;
	const TEST_CULL=true;
	var t,u,v;

	var Triangle = (function () {
		function Triangle(vert0,vert1,vert2) {
			this.vert0=vert0;
			this.vert1=vert1;
			this.vert2=vert2;
			this.intersect = function (ray) {
				var orig,dir,edge1,edge2,tvec,pvec,qvec,det,inv_det;
				orig=ray.start;
				dir=ray.dir;
				vert0=this.vert0;
				vert1=this.vert1;
				vert2=this.vert2;
				// debugger;
				edge1=Vector.minus(vert1,vert0);
				edge2=Vector.minus(vert2,vert0);
				pvec=Vector.cross(dir,edge2);
				det=Vector.dot(edge1,pvec);

				if(det<EPSILON){
					return null;
				}
				tvec=Vector.minus(orig,vert0);
				u=Vector.dot(tvec,pvec);
				if(u<0.0||u>det){
					return null;
				}
				qvec=Vector.cross(tvec,edge1);
				v=Vector.dot(dir,qvec);
				if(v<0.0||u+v>det){
					return null;
				}
				t=Vector.dot(edge2,qvec);
				inv_det=1.0/det;
				t*=inv_det;
				u*=inv_det;
				v*=inv_det;

				return { thing: this, ray: ray, dist: t };
			}
		}
		return Triangle;
	}());

	var triangle=new Triangle(new Vector(0,0,5), new Vector(0,0,0), new Vector(10,0,0))
	var result= triangle.intersect({
		start:new Vector(1,-1,1),
		dir:new Vector(0,1,0),
	})
	console.log(result)

	// var triangle=new Triangle(new Vector(0,0,0), new Vector(2,0,4), new Vector(9,0,0))
	// var result= triangle.intersect({
	// 	start:new Vector(0,10,-20),
	// 	dir:new Vector(0.08203525365629483,-0.38466057993643654,0.9194054901948931),
	// })
	// console.log(result)

	// var triangle=new Triangle(new Vector(0,0,0), new Vector(2,0,4), new Vector(9,0,0))
	// var result= triangle.intersect({
	// 	start:new Vector(0,10,-20),
	// 	dir:new Vector(3.9,-3.8,9.2),
	// })
	// console.log(result)

	/*var triangle=new Triangle(new Vector(0,0,0), new Vector(2,0,4), new Vector(9,0,0))
	var ray={
		start:new Vector(0,10,-20),
		dir:new Vector(0.07603525365629483,-0.38466057993643654,0.9194054901948931),
	}
	var result= triangle.intersect(ray)
	console.log(result)*/


	function draw(triangle, ray){

		var scene = new THREE.Scene();
		var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );

		var renderer = new THREE.WebGLRenderer();
		renderer.setSize( window.innerWidth, window.innerHeight );
		document.body.appendChild( renderer.domElement );

		var controls = new THREE.OrbitControls(camera , renderer.domElement);

		scene.add( new THREE.AmbientLight( 0x888888 ) );

		var light = new THREE.PointLight( 0xffffff );
		light.position.set(-10,10,10);
		scene.add( light );



		/*var shape = new THREE.Shape();
		shape.moveTo( triangle.vert0.x, triangle.vert0.z );
		shape.lineTo( triangle.vert1.x, triangle.vert1.z );
		shape.lineTo( triangle.vert2.x, triangle.vert2.z );
		var extrudeSettings = { 
			steps: 1,
			amount: .01,
			bevelEnabled: false,
			// bevelSegments: 2,
			// bevelSize: 1,
			// bevelThickness: 1 ,
		};
		var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
		var material = new THREE.MeshLambertMaterial( { color: 'red', wireframe: false } );
		var mesh = new THREE.Mesh( geometry, material );
		mesh.rotateX(Math.PI/2)
		scene.add(mesh);*/

		var geo_triangle=new THREE.Geometry()
		geo_triangle.vertices.push(
			new THREE.Vector3( triangle.vert0.x, triangle.vert0.y, triangle.vert0.z  ),
			new THREE.Vector3( triangle.vert1.x, triangle.vert1.y, triangle.vert1.z ),
			new THREE.Vector3( triangle.vert2.x, triangle.vert2.y, triangle.vert2.z )
		);
		geo_triangle.faces.push( new THREE.Face3( 0, 1, 2 ) );
		geo_triangle.computeBoundingSphere();
		var mtl_triangle = new THREE.MeshLambertMaterial( { color: 'red', wireframe: false } );
		var mesh_triangle = new THREE.Mesh( geo_triangle, mtl_triangle );
		scene.add(mesh_triangle)

		var geo_ray=new THREE.Geometry()
		geo_ray.vertices.push(
			new THREE.Vector3( ray.start.x, ray.start.y, ray.start.z  ),
			new THREE.Vector3( triangle.vert1.x, triangle.vert1.y, triangle.vert1.z )
		)


		// helper
			var helper={};
			helper.gridHelper = new THREE.GridHelper( 20 , 20 );
			scene.add( helper.gridHelper );

			helper.geometry_x = new THREE.BoxGeometry( 10 , 0.1 , 0.1 );
			helper.material_x = new THREE.MeshBasicMaterial( {color:'red'});
			helper.mesh_x=new THREE.Mesh(helper.geometry_x,helper.material_x);
			helper.mesh_x.position.x=5;
			helper.gridHelper.add(helper.mesh_x);

			helper.geometry_y = new THREE.BoxGeometry( .1 , 10 , 0.1 );
			helper.material_y = new THREE.MeshBasicMaterial( {color:'green'});
			helper.mesh_y=new THREE.Mesh(helper.geometry_y,helper.material_y);
			helper.mesh_y.position.y=5;
			helper.gridHelper.add(helper.mesh_y);

			helper.geometry_z = new THREE.BoxGeometry( .1 , .1 , 10 );
			helper.material_z = new THREE.MeshBasicMaterial( {color:'blue'});
			helper.mesh_z=new THREE.Mesh(helper.geometry_z,helper.material_z);
			helper.mesh_z.position.z=5;
			helper.gridHelper.add(helper.mesh_z);

		camera.position.set(10,10,10)
		camera.lookAt(new THREE.Vector3())

		var animate = function () {
			requestAnimationFrame( animate );

			renderer.render(scene, camera);
		};

		animate();
	}

</script>
</body>
</html>
